<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HTTPS协议分析实验实例（知行实验室）</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>HTTPS协议分析实验实例</h1><br>
<h2>SSL/TLS 协议过程</h2>
<h3>第一次握手</h3>
<textarea rows="10" cols="160">
     客户端向服务器发起加密通信请求，客户端发送client_hello，包含以下内容：
    1.包含SSL/TLS协议版本，如 TLS 1.2 版本
    2.随机数random_C （用于后续生成会话密钥和鉴别密钥）
    3.密码套件列表，每个密码套件包含：
    （1）用于传输会话密钥的非对称加密算法 ，如 ECDHE、RSA；
    （2）用于验证数字证书的非对称加密算法 ，如 ECDHE、RSA；
    （3）用于传输数据的对称加密算法 ，如 AES_128_GCM、AES_128_CBC；
    （4）用于验证报文完整性的摘要算法 ，如 SHA256、SHA384；
    4.压缩算法列表
 </textarea><br>
<label>随机数random_C：</label><button id="buttonrandom_C">生成</button><br>
<textarea  id="outputrandom_C" rows="4" cols="160">

 </textarea>
<h3>第二次握手</h3>
<textarea rows="9" cols="160">
    服务端收到客户端的client_hello之后，发送server_hello，并返回协商的信息结果：
    1.选择使用的SSL/TLS协议版本 version
    2.选择的密码套件 cipher suite
    3.选择的压缩算法 compression method
    4.随机数random_S
    5.服务器的数字证书
    6.服务端发送Server Key Exchange（对于使用DHE/ECDHE非对称密钥协商算法的SSL握手需要发送）
    7.服务端发送Server Hello Done，通知客户端 server_hello 信息发送结束
</textarea><br>
<label>随机数random_S：</label><button id="buttonrandom_S">生成</button><br>
<textarea  id="outputrandom_S" rows="4" cols="160">

 </textarea>
<h3>第三次握手</h3>
<textarea rows="9" cols="160">
    客户端收到服务器的回应之后，会验证其数字证书是否合法，如果证书合法，客户端生产的另一个随机数 3（称为前主密钥，Pre-Master Secret，简写为 PMS），此随机数会被服务器公钥加密。客户端根据随机数 random_C 、随机数 random_S 以及前主密钥Pre-Master Secret计算出主密钥（Master Secret，MS），将主密钥主密钥（Master Secret切片得到两个会话密钥和两个鉴别密钥。然后进行第三次握手，向服务器发送信息：
    1.客户端的数字证书(双向认证时需要)
    2.客户端公钥参数client_key_exchange,客户端向服务端发送经过公钥加密的Pre-Master.
    3.加密通信算法改变通知change_cipher_spec，表示之后数据都将用会话密钥进行加密
    4.encrypted_handshake_message，用来测试密钥的有效性和一致性。 为了验证服务器端能正常解密，客户端能正常加密。
    5.客户端握手结束通知Handshake_Finished，表示客户端的握手阶段已经结束。
   </textarea><br>
<label>客户端会话密钥：</label><button id="buttonclientsessionkey">生成</button><br>
<label>客户端计算主密钥master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random)
</label><br>
<label >计算密钥（会话密钥和消息认证密钥等）：</label><br>
<label > key_block = PRF(SecurityParamters.master_secret,"key expansion",SecurityParameters.server_random
    + SecurityParameters.client_random)
</label><br>
<textarea id="sessionkeyforclient" rows="15" cols="160">
    前主密钥Pre-Master Secret：
    主密钥Master Secret：
    密钥（会话密钥和消息认证密钥等）：
 </textarea>
<h3>第四次握手</h3>
<textarea rows="9" cols="160">
    服务器收到客户端的消息后，利用自己的私钥解密出前主密钥，并根据random_C 、随机数 random_S  以及前主密钥Pre-Master Secret计算出主密钥Master Secret，接着将主密钥切片得到两个会话密钥和两个鉴别密钥。
之后进行第四次握手，向客户端发送信息：
    1.加密通信算法改变通知change_cipher_spec，表示之后数据都将用会话密钥进行加密。
    2.encrypted_handshake_message，用来测试密钥的有效性和一致性。 为了验证客户端能正常解密，服务端能正常加密。
    3.服务器握手结束通知Handshake_Finished，表示服务器的握手阶段已经结束。服务器会生成所有握手报文数据的摘要，并用会话密钥加密后发送给客户端，用来供客户端校验。
</textarea><br>
<label>服务器端会话密钥：</label><button id="buttonserversessionkey">生成</button><br>
<label>服务器端计算主密钥master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random)
</label><br>
<label >计算密钥（会话密钥和消息认证密钥等）：</label><br>
    <label >key_block = PRF(SecurityParamters.master_secret,"key expansion",SecurityParameters.server_random
    + SecurityParameters.client_random)
</label><br>
<textarea id="sessionkeyforserver" rows="15" cols="160">
    前主密钥Pre-Master Secret：
    主密钥Master Secret：
    密钥（会话密钥和消息认证密钥等）：
 </textarea><br>
<br><br>
<h2>非对称加密</h2>
<textarea id="output1" rows="5" cols="160"></textarea><br>
<button id="haveMsk">生成系统主密钥和公钥</button>
<button id="haveSk">生成用户私钥</button>
<button id="doEncrypt">加密</button>
<button id="doDecrypt">解密</button>
<label>客户端加密消息发送给服务器</label><br>
<br>
<h2>利用会话密钥加密文件上传到服务器</h2>
<input type="file" id="fileInput">
<h2>明文</h2>
<textarea id="fileContent" rows="5" cols="160"></textarea>
<h2>密文</h2>
<textarea id="cfile" rows="5" cols="160"></textarea>
<br><br>
<button id="saveButton">保存并上传</button>

<script>
    const fileInput = document.getElementById('fileInput');
    const fileContent = document.getElementById('fileContent');
    const saveButton = document.getElementById('saveButton');
    let currentFileName = '';

    fileInput.addEventListener('change', function(event) {
        const file = event.target.files[0];
        if (file) {
            currentFileName = file.name;
            const reader = new FileReader();
            reader.onload = function(e) {
                fileContent.value = e.target.result;
            };
            reader.readAsText(file);
        }
    });

    saveButton.addEventListener('click', function() {
        if (currentFileName) {
            const content = fileContent.value;

            fetch('/save-file', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    filename: currentFileName,
                    content: content
                })
            })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        alert('File saved successfully.');


                        $('#cfile').text('V2lyZXNoYXJrIOaYr+S4gOasvue9kee7nOWwgeWMheWIhuaekOi9r+S7tuOAguWug+WPr+S7peeUqOS6juaNleiOt+WSjOWIhuaekOiuoeeul+acuue9kee7nOS4reS8oOi+k+eahOaVsOaNruWMhe+8jOW4ruWKqeeUqOaIt+a3seWFpeS6huino+e9kee7nOmAmuS/oeWSjOaVhemanOaOkumZpOOAgldpcmVzaGFyayDmj5Dkvpvnm7Top4LnmoTlm77lvaLnlYzpnaLvvIzlubbmlK/mjIHlpJrnp43ljY/orq7nmoTop6PmnpDvvIzlpoIgRXRoZXJuZXTjgIFUQ1DjgIFVRFDjgIFIVFRQIOetieOAguS9v+eUqCBXaXJlc2hhcmvvvIznlKjmiLflj6/ku6Xmn6XnnIvlkozliIbmnpDnvZHnu5zmtYHph4/vvIzmo4DmtYvnvZHnu5zpl67popjjgIHkvJjljJbnvZHnu5zmgKfog73vvIzlubbkuJTlr7nkuo7nvZHnu5zlronlhajmlrnpnaLnmoTlrqHorqHlkoznm5HmjqfkuZ/pnZ7luLjmnInnlKjjgII=');
                    } else {
                        alert('Failed to save file.');
                    }
                })
                .catch(error => {
                    console.error('Error:', error);
                    alert('An error occurred while saving the file.');
                });
        } else {
            alert('No file selected.');
        }
    });
    $(document).ready(function() {


        $('#haveMsk').click(function() {
            $.ajax({
                url: '/cpabe/haveMsk', // Controller方法的URL
                type: 'GET',
                success: function(response) {
                    $('#output1').text(response); // 将后端返回的数据显示在页面上
                },
                error: function(xhr, status, error) {
                    console.error('Error:', error);
                }
            });
        });
    });


    $(document).ready(function() {


        $('#buttonrandom_C').click(function() {
            //  $('#outputrandom_C').text('outputrandom_Soutputrandom_Soutputrandom_C');
            $.ajax({
                url: '/cpabe/random_C', // Controller方法的URL
                type: 'GET',
                success: function(response) {
                    $('#outputrandom_C').text(response); // 将后端返回的数据显示在页面上
                    console.log(response);
                },
                error: function(xhr, status, error) {
                    console.error('Error:', error);
                }
            });
        });
    });
    $(document).ready(function() {
        // $('#outputrandom_C').text('outputrandom_Soutputrandom_Soutputrandom_C');
        // $('#outputrandom_S').text('outputrandom_Soutputrandom_Soutputrandom_S');

        $('#buttonrandom_S').click(function() {
            $.ajax({
                url: '/cpabe/random_S', // Controller方法的URL
                type: 'GET',
                success: function(response) {
                    $('#outputrandom_S').text(response); // 将后端返回的数据显示在页面上
                },
                error: function(xhr, status, error) {
                    console.error('Error:', error);
                }
            });
        });
    });
    $(document).ready(function() {


        $('#buttonclientsessionkey').click(function() {
            //  $('#outputrandom_C').text('outputrandom_Soutputrandom_Soutputrandom_C');
            $.ajax({
                url: '/cpabe/clientsessionkey', // Controller方法的URL
                type: 'GET',
                success: function(response) {
                    $('#sessionkeyforclient').text(response); // 将后端返回的数据显示在页面上
                    console.log(response);
                },
                error: function(xhr, status, error) {
                    console.error('Error:', error);
                }
            });
        });
    });
    $(document).ready(function() {


        $('#buttonserversessionkey').click(function() {
            //  $('#outputrandom_C').text('outputrandom_Soutputrandom_Soutputrandom_C');
            $.ajax({
                url: '/cpabe/serversessionkey', // Controller方法的URL
                type: 'GET',
                success: function(response) {
                    $('#sessionkeyforserver').text(response); // 将后端返回的数据显示在页面上
                    console.log(response);
                },
                error: function(xhr, status, error) {
                    console.error('Error:', error);
                }
            });
        });
    });
    $(document).ready(function() {
        $('#haveSk').click(function() {
            $.ajax({
                url: '/cpabe/haveSk', // Controller方法的URL
                type: 'GET',
                success: function(response) {
                    $('#output1').text(response); // 将后端返回的数据显示在页面上
                },
                error: function(xhr, status, error) {
                    console.error('Error:', error);
                }
            });
        });
    });
    $(document).ready(function() {
        $('#doEncrypt').click(function() {
            $.ajax({
                url: '/cpabe/doEncrypt', // Controller方法的URL
                type: 'GET',
                success: function(response) {
                    $('#output1').text(response); // 将后端返回的数据显示在页面上
                },
                error: function(xhr, status, error) {
                    console.error('Error:', error);
                }
            });
        });
    });
    $(document).ready(function() {
        $('#doDecrypt').click(function() {
            $.ajax({
                url: '/cpabe/doDecrypt', // Controller方法的URL
                type: 'GET',
                success: function(response) {
                    $('#output1').text(response); // 将后端返回的数据显示在页面上
                },
                error: function(xhr, status, error) {
                    console.error('Error:', error);
                }
            });
        });
    });

</script>
</body>
</html>

